﻿using ScFramework.Core;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UnionManager : EntityInstanceMgr<SRigidUnion,SCollider>
{
   // Dictionary<ushort, int> belongUsr;



    public override void OnInit(object args)
    {
        base.OnInit(args);
    //    belongUsr = new Dictionary<ushort, int>();
    }
    public override void OnCreated1(List<SRigidUnion> comps)
    {
        base.OnCreated1(comps);
        List<SCollider> colliders = new List<SCollider>();
        foreach (var comp in comps)
        {

            foreach (var x in _compsDic2.Values)
            {
                if (x.AttachedRigidUnion == comp.SData.CompIdentity)
                {
                    if (TryAddToRigid(x, out Rigidbody2D rd))
                    {
                        colliders.Add(x);
                    }
                }
            }
        }
        SetRigid(colliders);
    }
    void SetRigid(List<SCollider> comps)
    {
        HashSet<SComponent> use = new HashSet<SComponent>();
        foreach(var x in comps)
        {
            var rd = x.GetComponentInParent<Rigidbody2D>();
            Debug.Assert(x.transform.parent.name.StartsWith("RigidUnion"));
            foreach (var y in x.GetComponents<SComponent>())
            {
                if (use.Contains(y) == false)
                {
                    y.SetRigid(rd);

                }
                use.Add(y);
            }
        }
    }
    public override void OnCreated2(List<SCollider> comp)
    {
        base.OnCreated2(comp);
        var nlist = new List<SCollider>();
        foreach(var x in comp)
        {

            if(TryAddToRigid(x,out Rigidbody2D rd))
            {
                nlist.Add(x);
            }
        }
        SetRigid(nlist);
    }
    public override void OnDeleted1(List<SRigidUnion> comp)
    {
        foreach (var x in comp)
        {
            x.transform.DetachChildren();
        }
        base.OnDeleted1(comp);

    }
    public override void OnValueChanged2(SCollider com, ushort vid, object v)
    {
        base.OnValueChanged2(com, vid, v);
        if (vid == SColliderVEx.AttachedRigidUnionId)
        {
            //    Debug.Log(v);
            if (TryAddToRigid(com, out Rigidbody2D rd))
            {

                foreach (var x in com.gameObject.GetComponents<SComponent>())
                {
                    x.SetRigid(rd);
                }
            }

        }
    }
    /// <summary>
    /// 设置interface所附属的rigid
    /// </summary>
    /// <param name="com"></param>
    bool TryAddToRigid(SCollider com,out Rigidbody2D rigidbody)
    {
        UInt32 id = ((UInt32)com.AttachedRigidUnion);
        if(com.Rigid!=null&&Get1(id)is SRigidUnion rigid)
        {
            if (rigid.GetComponent<Rigidbody2D>() == com.Rigid)
            {
                rigidbody = null;
                return false;
            }
        }

        if (com.Rigid != null)
        {
            foreach(var x in com.gameObject.GetComponents<SComponent>())
            {
                x.ClearRigid();
            }
        }
        if(Get1(id) is SRigidUnion tg)
        {
            com.gameObject.transform.SetParent(tg.gameObject.transform);
            com.AttachedCollider.density = (float)com.Mass/ com.AttachedCollider.GetArea();
            com.SyncValue(STransformVEx.LocalPositionId);
            com.SyncValue(STransformVEx.LocalIsFlipedId);
            com.SyncValue(STransformVEx.LocalRotationId);
            rigidbody = tg.GetComponent<Rigidbody2D>();
            return true;
        }
        else
        {
            Debug.LogWarning($"{com}所附属的rigid未找到");
            rigidbody = null;
            return false;
        }
    }
    /*
    void RefreshBelongCore()
    {
        belongUsr.Clear();
        var cores = new List<SCore>();
        foreach(var x in _compsDic2.Values)
        {
            if(x is SCore c)
            {
                Debug.Assert(belongUsr.ContainsKey(c.EntityId) == false);
                belongUsr[c.EntityId] = c.Entity.GetComponent<SComBody>().UserID;
                cores.Add(c);
            }
        }
        bool flag = true;
        while (flag)
        {
            flag = false;
            foreach(var x in _compsDic2.Values)
            {

                if (belongUsr.ContainsKey(x.EntityId))
                {
                    if (Get1(x.AttachedRigidUnion) == null)
                    {

                    }
                    var rid = Get1(x.AttachedRigidUnion).EntityId;
                    Debug.Assert(belongUsr.ContainsKey(rid) == false || belongUsr[rid] == belongUsr[x.EntityId]);
                    if (belongUsr.ContainsKey(rid) == false)
                    {
                        belongUsr[rid] = belongUsr[x.EntityId];
                        flag = true;
                    }
                }
            }

            foreach(var x in _compsDic2.Values)
            {
                if (belongUsr.ContainsKey(x.AttachedRigidUnion.left()))
                {
                    if (belongUsr.ContainsKey(x.EntityId) == false)
                    {
                        flag = true;
                        belongUsr[x.EntityId] = belongUsr[x.AttachedRigidUnion.left()];
                    }
                }
            }
        }



    }*/
    public void UpdateBeforeFunc()
    {
     //   RefreshBelongCore();
    }

    public void UpdateBeforePhysicSimu()
    {
    }

   /* public int GetBelongUser(ushort eid)
    {
        if (belongUsr.ContainsKey(eid))
        {
            Debug.Assert(belongUsr[eid] > 0);
            return belongUsr[eid];
        }
        else
        {
            return 0;
        }
    }

    public List<ushort> GetAllEntitiesByUserID(int usr)
    {
        List<ushort> ans = new List<ushort>();
        foreach(var x in belongUsr)
        {
            if (x.Value == usr)
            {
                if (Get1ByEid(x.Key) == null)
                {
                    Debug.Assert(ans.Contains(x.Key) == false);
                    ans.Add(x.Key);

                }
            }
        }
        return ans;
    }*/

}

